{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Captum Visual Insights for BERT Seq Classification Model"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "This Notebook helps you to get started with the Captum Insights.The example covered here is from the Hugginface Transformers pre-trained model used in Torchserve.In order to understand the word importances and attributions when we make an Explanation Request, we use Captum Insights"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import json\n",
    "import captum\n",
    "from captum.attr import visualization as viz\n",
    "import os\n",
    "import logging\n",
    "import numpy as np\n",
    "import json\n",
    "import torch\n",
    "from transformers import AutoTokenizer"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Create the mar file for the BERTSeqClassification model and place the artefacts from where you can serve the model. \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "/bin/sh: 1: torch-model-archiver: not found\r\n"
     ]
    }
   ],
   "source": [
    "!torch-model-archiver --model-name bert_explain --version 1.0 --serialized-file Transformer_model/pytorch_model.bin --handler Transformer_model/Transformer_handler_generalized.py --extra-files \"Transformer_model/config.json,Transformer_model/setup_config.json,Transformer_model/index_to_name.json,Transformer_model/vocab.txt\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Accepted"
     ]
    }
   ],
   "source": [
    "#curl request to make a Prediction Request\n",
    "!curl -H \"Content-Type: application/json\" --data @examples/Huggingface_Transformers/bert_ts.json http://127.0.0.1:8080/predictions/bert_explain"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Make a Explanation response for the bert model by specifying body in the service envelope in the config.properties file, like below:\n",
    "\n",
    "```\n",
    "service_envelope=body\n",
    "```\n",
    "When a json file is passed as a request format to the curl, Torchserve unwraps the json file from the request body. This is the reason for specifying service_envelope=body in the config.properties file"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{\r\n",
      "  \"importances\": [\r\n",
      "    0.0,\r\n",
      "    -0.6324464886855062,\r\n",
      "    -0.03311582455592391,\r\n",
      "    0.26816950103292936,\r\n",
      "    -0.29124773714666485,\r\n",
      "    0.5422589134206756,\r\n",
      "    -0.3848765077942276,\r\n",
      "    0.0\r\n",
      "  ],\r\n",
      "  \"words\": [\r\n",
      "    \"[CLS]\",\r\n",
      "    \"bloomberg\",\r\n",
      "    \"has\",\r\n",
      "    \"reported\",\r\n",
      "    \"on\",\r\n",
      "    \"the\",\r\n",
      "    \"economy\",\r\n",
      "    \"[SEP]\"\r\n",
      "  ],\r\n",
      "  \"delta\": -0.0007350820187373014\r\n",
      "}"
     ]
    }
   ],
   "source": [
    "#curl command to make an Explanation Request and the response is as below:\n",
    "#bert_ts.json file contains the input for the inference request\n",
    "!curl -H \"Content-Type: application/json\" --data @examples/Huggingface_Transformers/bert_ts.json http://127.0.0.1:8080/explanations/bert_explain"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The above explanation response is present in the bert_response.json. From the BERT_Response.json file the attributions, importances and delta key-value pair are loaded"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "input_file=open('./bert_response.json', 'r')\n",
    "input_json = json.load(input_file)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "attributions = input_json['explanations'][0]['importances']\n",
    "words = input_json['explanations'][0]['words']\n",
    "delta = input_json['explanations'][0]['delta']\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "For visualization purpose using Captum, the attributions and delta parameters should be in the form of Torch Tensors. "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Making the arguments ready to be passed on to the VisualizationDataRecord method.The argument for predictions is given as 1(a random probability) in the VisualizationDataRecord method since it is not mandatory "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "\n",
    "attributions = torch.tensor(attributions)\n",
    "predictions = 1\n",
    "label = 'Not Accepted'\n",
    "true_label = 'Accepted'"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Using the Visualization Data Record method from Captum's Visualization toolkit to render the visualization"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [],
   "source": [
    "\n",
    "result = viz.VisualizationDataRecord(\n",
    "                        attributions,\n",
    "                        predictions,\n",
    "                        label,\n",
    "                        true_label,\n",
    "                        label,\n",
    "                        attributions.sum(),       \n",
    "                        words,\n",
    "                        delta)    \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<table width: 100%><tr><th>True Label</th><th>Predicted Label</th><th>Attribution Label</th><th>Attribution Score</th><th>Word Importance</th><tr><td><text style=\"padding-right:2em\"><b>Accepted</b></text></td><td><text style=\"padding-right:2em\"><b>Not Accepted (1.00)</b></text></td><td><text style=\"padding-right:2em\"><b>Not Accepted</b></text></td><td><text style=\"padding-right:2em\"><b>-0.04</b></text></td><td><mark style=\"background-color: hsl(0, 75%, 100%); opacity:1.0;                     line-height:1.75\"><font color=\"black\"> [CLS]                    </font></mark><mark style=\"background-color: hsl(0, 75%, 95%); opacity:1.0;                     line-height:1.75\"><font color=\"black\"> the                    </font></mark><mark style=\"background-color: hsl(120, 75%, 87%); opacity:1.0;                     line-height:1.75\"><font color=\"black\"> recent                    </font></mark><mark style=\"background-color: hsl(0, 75%, 98%); opacity:1.0;                     line-height:1.75\"><font color=\"black\"> climate                    </font></mark><mark style=\"background-color: hsl(120, 75%, 96%); opacity:1.0;                     line-height:1.75\"><font color=\"black\"> change                    </font></mark><mark style=\"background-color: hsl(120, 75%, 76%); opacity:1.0;                     line-height:1.75\"><font color=\"black\"> across                    </font></mark><mark style=\"background-color: hsl(0, 75%, 82%); opacity:1.0;                     line-height:1.75\"><font color=\"black\"> world                    </font></mark><mark style=\"background-color: hsl(120, 75%, 76%); opacity:1.0;                     line-height:1.75\"><font color=\"black\"> is                    </font></mark><mark style=\"background-color: hsl(0, 75%, 89%); opacity:1.0;                     line-height:1.75\"><font color=\"black\"> impact                    </font></mark><mark style=\"background-color: hsl(0, 75%, 87%); opacity:1.0;                     line-height:1.75\"><font color=\"black\"> ##ing                    </font></mark><mark style=\"background-color: hsl(0, 75%, 98%); opacity:1.0;                     line-height:1.75\"><font color=\"black\"> negatively                    </font></mark><mark style=\"background-color: hsl(0, 75%, 100%); opacity:1.0;                     line-height:1.75\"><font color=\"black\"> [SEP]                    </font></mark></td><tr></table>"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "viz.visualize_text([result])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAA24AAAAzCAYAAADvqVvTAAAABHNCSVQICAgIfAhkiAAAABl0RVh0U29mdHdhcmUAZ25vbWUtc2NyZWVuc2hvdO8Dvz4AACAASURBVHic7d15XFVl4vjxTz9JDmpfL2HDZahhMRNwYTEFbmPq9avkJTWhNGDSBMcFLJXIhSH3cN/FLdGsAQcdMCQuotMVtEAyWTQFsuJaMlxK81ZMHu367ffHvRgiqytNz/v1svThnOc85zz7ec45PPDLL7/8QjN++umn5jYRBEEQBEEQBEEQGtChQ4fbjuP/3YF0CIIgCIIgCIIgCHeRmLgJgiAIgiAIgiC0cWLiJgiCIAiCIAiC0MaJiZsgCIIgCIIgCEIbd98mbsbdodh17EjH+n+cIsk23cED1aQQat+RPvNKWr5PbjQ97HoQm9fSHarZOsIOu1G7MN5KGts6yzW8nkd2jvQYFM7Wwts42/J1qO3sCN8PmNIJt7dDvbKsyV2MhSls1VW3/BimAmJ729Fjds6N4b/VMiFnE/lERzp27nNTOsrS1pFeXvsvPdmbUyiRm0vXLaaxOodd7xaY92lh3rXIbyJfjKSEONKx483nfGP5bCoPoGypCjvHcNJNN/695erGf4fL2hfpxL6gwtXRzlzX+4eyPPe/smUTBEH4/TGVsKBfRxxfSkEGMBWwwKcjHe2C2GXpwsqWqrCzD2LXhVs9RiPjL/Ss09hhp1mH/lbTf4taPYZso+7bxE0xZC7aQzp02nkEdAL70avJPKRDt3cmvlb3K1VCU5xDN5GpzSTz3bn4/ied6AnLKbgTk2yrAJZ8fILdE9ya2MhI7oZo1h/U34ED/jbJR9I5UC0hWZWRvr/g1x+YctgWt5z0Lyz/Pr2HBfNTKK5pKBZ7xr11ghNbxqC4xXRU719B7I5cDNDCvPsvciGb9CNGpE5QkrmfX6du9cpnk3kAbpP3cSJvNQG32tbdEP/t5+mvjOyKi2TdF14s2fcRJw5tYqSUy4IpC8lpZBIqCIIg/IZYdcevnz3GkhJKTEB1MR+fk5AopqBEBoyUlJSDxwB8u9zvxN4p/z1jyPv3qGQXN3xVvvg+1R2FFdjYezFQ5YtvP0jR2GEXEkvsEFdU80rImd0Du96x5klCvVm8fHoXkUN64Ghvh2u/UJbnteLOsElPynQ1PRztsHPqQeC8bOrOxQ2Z0aifsMPOVU30/urbP95vnPRHLwYOGMhAzSSmBXWHc2WUGfVsrZdfjV0jY+5ygno7YufUh9CdJVwfB5qymdOvDyHbzcPgau0CgnwcsbNzpIcmmvQvIHtqD0L3GNFvUOM4ORuMBWz9q3lVwPEJFeFvWeKrziZ2iCt29q6opqagb+3Ess2WCZnc/QeodhrHqy/YY9CmX68PC/oFsvWckZQX7AhavQz10wsoqckmsruadUUphNrbERizgKAnXInUVbPrr33oMznl19WZKyWsC+mDo70jfV5YR0kNsD8cOzs16yyreNmTHbHrv5zju0PxmJ6D8eMF9OkdS4FcL+9ylxPq74qdnR2OPoFE7ylDBkoWqbDziGT50iB6ONrh2C+cXeU3n2Wj2ki+GA+lkyt7MmlqANLJA+yvvT51y2dY1I15UH5zHSnbMoo+qug6TxcYKVhkuTb+lmtTvYsgOzuC3rXUn3eDsLMLYlfBunrx18vTc+nEjuqDq70ddq59CJqXTbUJ0EXjaqciem0sgR522Lmqrl+rOlcSo0FG6miP8xNuuPmMJH7faSoLVzNQAmpK2DrZkg+uKkLXWlZe5TJSpgfSw8kOO0dXVOOXk3MByypq3fL3+25DBUEQ7j8JX18vpMoSiqtBLimhtPMAAny/p7igHEzllJwGpa8fbhgp2ByO2sMyJhsSydZC8+jN3K+HEztVhaNmHfpWj79q+8YFLH+hB472rqjnpZO9NJAe9na4jlhOQQ2WvqsP4bMt6ajTzzfa39Xre0YG1RtDNjamaKKflL9IIVrTA0c7Oxx9glhw8P7MC9rgO242YAXykWPwyj52RHZvYtsytk6P5sCjcymsrGRfkIFlU9e1eBVI/ngPKZ8pmZhRyRcbfCnduIAtJy0/NBko+MaXTYe0zOpZztbZy8gx3d7xfvtkZBPIFwrIPnIOHN1wU9TPrwcauUZlbItbRm7niaTmaZloXUZ5Q3fwL6QwY8p6zj29iRMn0xj9cwoz4nbhtTKJaV0lnF/J5IuNARSsiCT2hB87Tl/k9BY/SuJmsPULyFkTzboz7sw9lE+yRqa8snXLBG22TNTkkq6txlkzgmlBz9C5Mp30jwErX+a9Ow9fScGYdytJi57F7pUBSFIAm07qmOYuISFz7Eg1I/+uZV6/Bs65pBybV1L5YPNIOLiQ2N2NP0rwUMgOdoQqkPrNI+/j+BtXxy+kM2f8Ako8l/DRmRPsGHqJXa9EsrUcrB8EKg9QbBePLmsuXpUpLN+Z0+LTbxv5YiR9fy6yx3OMnTiSAVIJBzLME9aAuuVzV8KNedC9BW1aTTFlynlkZsUzoDqF2KXpjT/26DytXvx1f6hn6yvhbDUEsPnjM3y01JPyteHM2F0N7cDGVE5umScJh7S86lTOrhW7uPGBTzdGTgxAeWY56u6uqEaEE70lm/LvzT8tWRFObIYNEzPO8NECN0pWRLLuYyhZG07kXhi3+wxnsmahzF1A+PxsZKv65e/33oYKgiDcf4p+fnhSTEmJTPmJYr73DGBMbyXlhcVUVxZTUinhq/JEzl1I+OwclDO0nDmZxrgHU4iesJACk6Vfr86h5NF5aDeMQ9/q8Zelb8wrofMbmWwaZUPBxhls7byKzM1jsMldx9aDsqXvKqPENJa0kx+xuk9tP99Ef1ev79m27cYxZKNjikb7ST1bX4lk1+XRJJ08wQ61gW3TF5Bdc+/7tDY4cTOTPEYycYQnbvZS4xsZSyg4KVOtjcana1c0G0qguoSyiy08hpMnnh31bHv5KQbHZfO9ycD315/n7UxAyBjcnHwZPcQLqbqc8tLbO95vXdlKNXadO2LnpGbB6e5MWznt+sD9en5ZlzZ8jb4qofgzGeehzzHQ0Z6Bo5+je0OPiRXmcszYmQGjRuLs6Mu8Q5V8uXsc9lY2lg1skKz0HPtYj3xuF2GejvQYn4KeckpOl1N+0oDkOYKRve1x1oxmgGPrzrGtlgn5SDoHLjozcthAFE+P5JnO+l8fl7SytiTeXFesa6+rNWD5u/OwcYzr54Z9pwbO2XMEo1XOuI0Yja+dTOnp0iZSIiG1s0Rfv2oWZpNz0d58jeydCQgNoLtcQm7tu5CSHyND3LDvHcAAVwlD9fe0dFrdJvKlOp10nUz3kSNwsw9g5NMSJemWxyVvKJ/18qD2HJpq0yQ/xrzkiXPvcYz0lTCeLuZcEw1/Q/EDYCwgt0Cm+8gxBDjZ4xY0lgB7I7kfFVs26MyA0WNwdvRlQB8l8kUDhnrHcQ5J5kRhJjvmj8Ovs57sFeGoh0STbdSTc1wPfUbwoo89bi/t4HTlCeb105NzpBz6jGCcyh773uMY85REdV4utW8rXi9/pt93GyoIgtAmdO2Hn71M8Ylcik+W4+zjxwAfT6SSAo6dKKHYygvfPhLlulz00kDGhHhi7+jL6OF+SOeOceycORoZP8ZODsCzq/GWx1+SZwDP9XbGz7c7Eu4EaNxwftqX7lYy1Rctdw2xZ8DwgSisnBmgru3nm+jv6o99FDf20c2NKW7qJy8UUHBCpnvAcwx0dCZgZR6VZzYRcB/6tDY7caOT4vr7GjY3/OAysnzjcM9zqpbKc5VUVl7kYmUa4+xbdoicNVNYfsKN+CMnOLFlHMpGt7x8R473W+f80g7yjuaR9/FpKst1xA+tc+J18gsauEZ/qBfZtcs05grANcs/ZCNGY8PDe8k3nsJzlVSeq+RidSU7RljfPBFo5V2PtlkmLI9JmvSs0/z6ArG+9nHJZkl0fqhz4z+2qq1jV2467hWT+f/ylVasXF678Z/XpylWUu3c8nqj2lJtIV+qD6aTWyNTMq8PHTs6Er7fiHzmPfafbmEE9epIwyzXuV2dIJM5X67I9fOnCT/X+3ft9bayuZ4HNlZ18ub6sYyU5WVTYvJjzJR5rH5Xx0ebx6A4l03umZvjlY1GrjfHpl+vvuUWguX/N5e/32sbKgiC0CZY+eHrK1F+PIXc053x7dMdRR9fuv+njPSMAmTXfvhdb5fl62Mrm3rRSJKE1Kl2q3paOv5qJ2FN7Q1Ja3MfZdXADc7asYWp3vixsf6uibFPk2OKpvrJ2mOZZIxG4/Vzvpd9WtuduNXRuYs9VB7jQGE1+v17yL2IuUAoPPHtLVF+MIWcympyVoYSOHlXg1+qkf9dTE5ujuVPASXnjFypsQyErlSTnZaDgSsYa2qzoZrsPenoKwvYk1WC7OiJl3vLj/ffSLJ3w9PHE88ezigaWwhtLE8kT7xcQX8whZxzerKTsylvqFJ7+jKgUzW5aeZrv3x4V7qO32V+9thKxlitp7rGGb9+zsgl+9lVWI1eG0vQiFjSq53x9FAil+xnT2E1ZWnvkN3EB4R+M2WiJpf0g9XYj95EXn4eefl56NaORHEunfSPsDRSMtXn9L8OojGg/9KI3IKGUz6xn10fV6Pfn07uRQkvT3fookRpOscxXRnVp1NI+ajePhcNnKuu10z7BDDQrprs3SmUVVvyWPJjgKp1n8xom/lSzYH9ucjdJ5FsyYM87TwGWpXzXpblYcPr5bN2n1bkgXyM9N3ma51eIGPf04vudgoUnWSKj+Sgry7hHxnF9TrGBuJX+DLAV6Jcu4vsc7V1wJ6Ap31bdppyAesnBKF5OZZdugJKPs4mJasEWXLGydEZP5UznNjPPwqr0e8Jp0/Xp4gtUDLw6e5wIoVdedVUn9zFro9knNUDbl5Vb0WbLQiCINwtEn79vKAgnfRqdzw9JXDyxMuuhHRtGZ19ze13d/UAnOVjpLxbQnVlAbsyiuGJZxjoVD++1o2/Ws8ytqgsYM/+2n6+lf3d9T5abmZM0QCFb52+S09OnJquPtFkc+/7tN/ExM0tZBrjPPSsH64m6uPuDPCQuGwCcGPS2tWMsUonuLcH4akwIGQkzg3EoU+OJFATaPmjZspuAwPCpxEgpRPuP4p0z1nMVVuT/kokKd/DZSs3fO2zCe2vYdnnnkxbOg1fq5Yf7/erkWtk5cbEN2fid3ErwYNCSenoh6fETaun2I8jfvM0lHmR9OkdxK4Hx7Fp5STsrbozdJgn7I/EPyYdz9c3Ea++xJZhHjwVcwzF8DEE2MPAGfFMci1l2TB/IvOc8O0ucbmRuvhbKROyLoUDF5157uUxePb2xLO3J74h4xhpryc9KwccB/KMb2eOxakJ31uNQjWSAPty1r8QxNbPmoncBFI/Ty6vUPPUlHSkEfHMC7GHfhOZOVpJwfzBqOOq8VIr4cplrpjAa+hI3C7uInz4whtX/LqMZMn2eXh+OoenPPowRafk1Z0JTLqpgW9am8yX6gOkHwHP0eMYackDzwETGa2WKE/fT1m98inVzYNmPsJy5WeQ7Pxw/uI11OpYjjmOY8nskUhSANNiArA5GMlTw5eBagAKriDL3JjHN8TvzKQNO5ikzCXcx4On4srwfGMHq0e3cPLcKYD4t1cz5qFcFoSoUQ0LZ32ZE5M2m/PR9/UdxGsusW6YB31mm+OeO0DCc/oOVofYsOcFDzyGrcc4eDXJcQNvXtFrRZstCIIg3D32vv1wlmVkJ8vqmpUXvp4g10j4+XohAdKAuexYOhDjBjUevYPYZTWGTW+/imcDT820ZvzValbOeHbOJby/hmXnavv5VvR3N/TR2fg2NqZo5EvQ4MykjZsYJ6UT1rsPYTolr25ZwkjFve/THvjll19+aW6jn3766S4mQRAEQRAEQRAEoZ7caHoEZTMy4zTxqvudmNvToUOH247jN7HiJgiCIAiCIAiC8HsmVtwEQRAEQRAEQRDuIrHiJgiCIAiCIAiC8DsgJm6CIAiCIAiCIAhtnJi4CYIgCIIgCIIgtHFi4iYIgiAIgiAIgtDGtejjJIIgCIIgCIIgCML9I1bcBEEQBEEQBEEQ2jgxcRMEQRAEQRAEQWjjxMRNEARBEARBEAShjRMTN0EQBEEQBEEQhDZOTNwEQRAEQRAEQRDaOKv7nQBBEARB+C36P8M3dyXeA8qyuxLv7dL81Pd+J6FZ33T46X4nocUWsfN+J6FRK1Nc73cSiBnz5S3vu+a4+g6m5M765afL9zsJADzY1+d+J+Hu6mBzv1NwV4gVN0EQBEEQBEEQhDZOTNwEQRAEQRAEQRDaODFxEwRBEARBEARBaOPuwMTNSHKQLQ88YINqSentR9cqFWg3JFMkt3wP485AbGwCSTTcvVS1RlGsBw88YIPPoqLrYfnRrtj4v0lzV7N07yrSGnsVQtYy4bEHeOBBD2I+vGPJbRmDjsSd+RhbsUtT+VK6QoXtY2EkG4DzWuKGumLzoCtTDzdy+Kw4BnezxeYhB1ThiZSaGg+v2ByIrUMwiedbe5J3z+2UCeMnySQcaqxwi7r6+2Mkf0kgHo/YYOPgQ/CGIm7Ogma2MSQT9tgDPOAwAa3pniW8ZT6MwdXFh8CJlnp+IZ9V4YPx6OaKazdXPNQTWPWhuSWSdwfjEK5tIBID2rnBqPr6oPL3wcd7MBPeKkI2lZIYHoiPi2uL2tDSg5nmNJgy+YtqDrq2dq1a4GrxEY7rb3HnmhSCe89AZ9KT8IKGVadvNzUGdPuLGyivt+ezRcN4fsO5Oxyr0LRvWBsfy9Kv6wVfO8X019by3s/N7H74fVLCy7h2K4f+ScfYl9dy7JZ2vlUXOJxT1sKye5Wst94i6ypQ+Q9mpf+78fDLuYydlHCPz+VOqFOXc+fgM/lAq+t10TwVgW/d2mCgdIkKB+/BBK/Ip9H2HkCfwOCHbHHt5YHH9T8+BG8oBVMRcb1scXD3wcfbB59eHvgMjSHtc8hfEcxgb4d7Nq66/YnbBS2ph41InaBof1qzA8s76tNk4mKTKKy5lwe9C6xkitYvNk9MWsqkI2HmYlLPNvxj+XAamQYJyaqUtLT8O5LMljLse5OYbTqq7kRkxjQWry7CPTKOUIWWCf2nki8pkRrbXtaxOHIVVf1XkvlOBOyLIWanodFwl7/GEdFFy5vLdXd8gHBbbqVMYES3OopVWRUN/1jU1d+f4pVELSzEPTaV1GgH8mZGsar+zZ4mtzGSFhuHVlbc44S3nOQfQ+q2CNwpZdXoMLQui8kr/ZIvz36Jbo6S1JfCSNQ3vr+cEcfUYjVJ+YXk5RdSmBUFOxaTZHAnYkcqMf6NtjZ1fEXWjvev3yT6rfpizz4+aaRPaTlnovZqea3HbUZjzCVhZ0GrbgAK/6UGPcuYHW60u5V9O6h55+3p+N3Szrfox0/Y/N7JlpXda/+m7JoD3u1BPnsRyfWPjYfbDOCdrVH39lzuhLp1ecASCrc80/gY7i7xCN9O6uv+jbf3tTfvnSNIKjrDmVO1fwpJfcXd/DMrd2L2FVJYVEjhqTOkjiolZmYy7q+nsj3c456dy21P3IxZqehkb6JmaJCKM29YATJkxBHobouNjS2u6qmkfd50eMW+GAa722LzkC0eQ+PQGoCaZIIfssEnPIZgbwdsHnJl8Fwdxs9XoeobR1GNlgmPqVhV1sj+yBRtCMbjERtsuwWyOP/S7Z7yHSf11KBRaFm8PP/myYM+jRiNBw4P2WDj4EFgrBaDnE9cr8Ek6I0kj7AhcGf95kFGty8Tg3MEr4UoqcpIJf/6gMKIbkkwPg422Dzkiio80bIK0li4Ad2iYDwcbLGxdUUVmUyFCTg0FQcbD8Kiw1C52GLjoGLqPgPGd4NxidRhPBaHR7cY8k23ly/GjCS0RhVhL7mDlTsRuwvJnKnCtrHvoX6qQ2dwQBMegXpUBGHeMnmH85AbC7fyJ2K0O1V7k9G1oZlbk2VCLiU5cjCuj9hgY+uAT+ib6C6AdqILwbuNVKxRYdvAyoKoq78/FYfzKZXUhE3RoJkShsqqCN1hQ4u3MR6KI+6oP3Hj3e95R9tqRxNJvBzBxjf8UVjaB+WQxWjzkwhzbmI/+TKX656dMojt+alEPNryQ5fumsOmTz5kddQStN8DVJO1YgrDXwyk55Ap7LDcS6nImM/w559neNjzDIlYgq7Zj1JW8f7QSNZFv0FsUApfmL6jZO4bxA6dxfyhM5gffQSDCeA7js+cRUz/GcT4z2DzbvNts6ufZrJu6AxiNbOIVS8i7VgN8B3vayJZt2gTmycuYn7/GWze9x18+C6Ju0/zycI3SDvWTLIu5PBmyCBUQwah0own8WTdVkrPqhGDePM0kDsDjxfm8GZMJGEjVAye9zaJi2YwYbwGn1HrzH2MXEbiZA0qjYbBQwYRuCgHI3qSZy9DV7KLiNnpGDCgWxTC4BFBBI7QEDg73dwPNeOrd2fxvP8wnvcfRljsIa5f7tIkooNCCPRW8fzco3wPoH+fOUOHETh0FM/3H8WcfdUAnFo0jOdfXc38idOZMnTYjdv3VxOoeZkpM+OZ0utl0moA43E2h47ieU0Iz6tHEb3zs+ZvCsrfcCZ8K6nqrbzXfyPvz/2cKwD8yLmZO0jtv5VU/60c2f0d1BRxsFcyR8K38t7cz3/dRr2D99UbeT/6FD+YgPOn+EizkfeGbuW9/pZ9Td/w2cQ6x5lZRpPf4LxWzuzZK/jHfwCMvL1iLH57LYW5bBd+G45h/PEUS9fO55ml8Twzfz6Tc84jA8V7X+eZt3bx3KK1vF23yfn2KJPnv87AFSt4ObkAfUtWjw7t5Z3QU1zDxLcbknmv/1beG7qR1KAPMDQ3O/rpAKODl3H42gU2Tx/PpK1rmbTodfpHxLFGu4eZ8XGMiBjPpA8uAJWsiQxj7IZlTJofx9CJk5l59AIAxoJNjJg4nqGvTKZ/5CJ26C1Z99kexkaOp3/kePrH/p1jP1aye+12DpenM3GtjqbuvRpPpTFrfQK7T59gTUICE1NPUHz4H/zzaMPhWV8fYkzYag5fg+J3JhOw/h1mrVzK2JjJBOw4YZ4YGXKZ9ko4T8/6G2O3vMXY8X/jH819xDJ3Bh4h5no64SUNqhfW1Rn/NVDv5DISxw/CRxNE8ORlxIT4MFVHy+qyLhLX8enk/k3F4A3660nIn+3D4M16MBawaryGwaOCGKzRMOHduiuXX5MwQkXMx7X/1rNKoyLuZDPnV9cdaO9rufRXofz6TIvaojvpNiduRlL36ZB7BhMRGYxaKiJzn+U+/oVkosJXUTEokTNntYT+nETUzEQMjYUbEpkangiRhVy+VEiUVQIRc7XIkoSETGmpLXFHKyiMVZK3IoYE+TXS1muQJA3bz+bxmqKR/c8nERebBqOSKDy6GAd9adtaWQHAm6iZGqp2xpGor5u6ChImhpFQpSHxVAWFq70pXRFG1G4XFu9djL+kIHTPJTLH17sbXqMjLcOAy/AgYl4IRHE+jVRLRyxnxTFhbh7u8YVUHI3CNiuGmA2ljYdnxBEWX0FQRhWXSxfjkhFFzG4jWIGNqZQiUwTas4Vs7FtKQvRiCkOSSHpJgeS3mMJTK/G/cHv5Upifh/y4PyolYOWCv5+i6QFklYEqFNgqABywVYBsqKKqsXDA3c8HhbGQojb1Be7GygQUrQgjYjdE7Kug4nAcDofjCIvVol6fymuPS7jM+ICqbZp68Ym6+ntkqKoCha15IiMpsO0EVVVVLdumJp/FM7V4L1yF5pH7kvxWMZSVInv7414vXKFsus2QhscQJ61C1U1F4MQ4Vu3Op6KVBc89bArD/vhnohPmoOkMfPcV0tA1ZPwjk3c1Z9mR8Rl8l8bMrTBj1z/JSPon257+lFcTPmkmZmvgK6ofm0B82hgeO7SdRP0QYg8uY/7BRQw1bCcl4ypXM7aT+PnT/O3oGlZmjKL9vn9Raqri/eh/oVy9hnjtMuJXO5P3+j6+BjB9xSXli0zZ9gbzl3Sj5K18Lv15DEH+D/Pk3EUE+TWdqvw1seh8N5N36DC6WW5oU3MaXV2Qz4F68SaS3pmGYvs2DEFr2L5zBxHsIukkcNGA7DsPrVbLB1lLcdcuJ6nSmdBXxuDecxyJS0eiOLiQmK9eJHV/Gpn7k4moXsCb2mYyyfB35sdfYXJWFv/M34Lmwj95vwzgCuWGPzF7z24yD8fyyLt/50MZvjcY6TbjbTIP7uOfO4dwNj6RUyaw5gpfGZ9gxra1bN4fdX37D1fP42zQTjK1b7N00Pec0IO1FZxaPpcPB23hn9rd/HN/NNbr55Ha3JMTF37gmv8zPKubxHOHh2Ob8QGfnYdrGQf46POeDDs6ieAMFe32FWHACgzf0H5iBM8tfNy8TVlPhunCeVY3Dlf9+xzLMPHTvjzOPzmK5w5O4rmsZ1HKP3Ll00KK9L0YopvEc0fH4eV+mf809RREOxcGdv2GY19eBbmMY7ih/LocA1B2tgJlDzfK9m/ngPMEDsyO5cDrIyDjHf5hBKkdlP3oypY3pvOy8tcoczL/ib7f6+S8/jpbnuqI4cfmnpOsw6SndL0Jj6xJPHdwKkP++hBXLrR8d/g3VX/8C1vfWMH6PmWszu9CbOxi9k9xIz/7Q0sZrsRg/xe2zl/MwZi+5GzdQ9G1K1QY/4fxsTs5uGELGcN+YGnKcaCSzWvTUUZu4eimnazvVUZynjUhocNwe3wk26arUTaRGkWvIJb97xMMCp7DsqgXGeQ2kAVRL/J8/4bDh3X5dV9rrqKvcWJOzGzeiQ/B/uD7HL4Kh/ckUPb0Yo4se5P13j9SYADrFqzQyeXgv3gT299NNtfNApAbqXdG7TLeNE1Gp00jdYEzFQWW2t+Culx7PXyDA7h0KJsKAFMBqTpnQkc4U7RmNrqnd/DBvjQ+2DMTaVMsSdW1qXyM4Bec0O3JMY8NvkhHyxgiere4ANyR9t5yxSjK0GHopcLlHv9itds7nCGVtEMy7rFBuCsdCB4kEZGWRumcv+F+XEeeUUHwC0G4PAqLj15iMUDWhMbDa4zIknJCkgAAEj1JREFUc32wXQjIMnLPIipM5m7YXaPBu5MEQ9S4zF1F4SmZqNrUS8Dx/Ib3/7SCQllpPp4Swkb5EHf0ts76LrDB4aU4ojapWBWvZWMnS7AxH12+jPvMMDTOSng0As3MZJKOFkLt4zvSzUMS+XAamRdcCBuuRuEvE6hIJC0tn5V/9qf0qI4KSc3KEHeUkjuZVa8BUBTbWHgeBrmCVcMcSACQZWyLCuFRACXqUWoUVqAe4oN0qJTS89L1QixJQNHt5IuMwWCERxxwuKWS2lhtrBf+iAsOZFL17a0c425ppExQge5wKfRdScSflSiJIKx/DNqjOooIvr6vVP96ibr6+2CSMdbIYAJJoaDxOlBXQ9tcoWh5FGkufyMvRMnlFXc4nXfFLU7zJW+i9pwhQl+E7rAW3b4oVAvdSTiURNAt3IUF4H96M8jT3DY7PGKPXPEDlB6n6OsPWRLxKUsAZCM89hVGnqTJB1GtHqarvxMAX3/yGdXH9cQP3Wf+2aX2tD9/ka+Nn9Gp7xhsAbo8TcQeoOYI7x8/x9fRMygB4ApXa3rynQmwUuLq/bA5DsVDdJJrLCs8LWGg8JSM92w3AKQBs0gdANSkNLi11N0Lbwmw6oxt5+64dwdQ4KCQKa0B7JTYfr6MiJAtSJJM6cXLBNebBZYWFlNxopTgEVst5y0hVRoA58aTWXqKT12epLcCwImwbeZ9P8Oa7v378wcroJM99tIVrsjQWWnPD5tmEb7TGmu+4itjP64A1ljzp7696AxgVbt9NZ+VWdNztDlfOg/6X/6sSAKqOf7JZ5w9NJnn95qTcRkZez00OYLv8j9Yn/0XuqCPaCeZuHThZ7oa4bviSqz7DqADQJdePLUHMJ3ipOSIw5PmRvW745VY+1u24SEc+j7EqaJqOozuRceQvbx/oRdOQ9zo+pIT1jJ0Ne0la/R3dB32OF1HeWPbqdFUAe3x83Bk6dlK5AfLMTg/wzOVRzj2n/4Yz8LAUCg+Bn61FaVjd/yU2yn+Gvx4ELdu3eudtpGyf4OX3x8AkJy649Whuv5BG2fliNPw7/hoWDLfBrnjNNwHp8dbvjt0wetx8+xHYdsF5w4u5rpn24XOl6+aW5B2jvj1cjRv7uSC28Usyq5YM8gOtmx7nd3trJEulnPpDz/CT+UUVbgwqps1AN4hi/EG+KLlKTKev4qiW3u4pkePEyHtmg7/VXuc3bqZ09/ODof2V7ly9SJlX7XHa5D5cUuFtz8DO73fonRIPbxQSQAKbBUyxiuN17uKC+Uo+8wyH9s+AI3vAoqgRXX5ut4j0VyKRVs5iahz76HrOoIYRwOpReWU6sIZbGniLnMZhzqvpCpHvYjPpj3oagbirs1GGrUDlxadYe2JNtHeA5xPIsJf9+vNPisXIt5KJcoNMJWy8gUfkiTABLa9wti+WoMCuJfPB93WxM2QlYauRkaO9eCBWEuglErap3/jb1i60dolRNmIUZZQNBEuoSRsTxUbh9Q5iCnNvFntTZkmliQb3P/QBPP+t3iO94yVNzGxQSSGLyZxSL3JWP0bUk3mmuUxSZOBVeoHWFUbnJFK/nJ/S2GUr19HucaIfH3Y0Eh4Jw2JFamE1m3gD5vz5Xp+mC4DDf+yw9vOl9aUUgclDhi59C3AJaqMICkdcHCoaji8FVHfc02VCRPUPv0gWf7b1KqCqKu/ExkROAQlIyOh2VbBRgcXMF7CaAJkI5dqwMHhxlKvbGgb+x/Rbi+iomwqLjZTwSQjm/IJ7iaReXYj6nt8h7EllL28YYeOIpMa7zrpMxzTcamnuvHOXTZiRIHC2RvNeG80419DHe5BQoaBoCm3+G6flXXD4T3H825SeJNj+Ju158E6lfux0FnEv+F0wxZfLGooDYDkzYv737AMyGp9Z151ux952MAxK96NZvHFSeTtHomCMt4cNKXBXd1Hb+YDy2SxNcdrMCduSsf3pMXO5uQQLTvG24Ph74QNauplP/nGeG6IT8Hg5ftYMqjlyfxh5z4+uaAiOK0X1nzDJ/57mt5BevDX970ebODnDwI9VTx7vBeXjn7OF7v38d5bPjyrVfGkbjoen3yOPquQg/6FPHk0lK5dGoij9mzc3FDklXPs/1Xi7BaCX7sD/OPsKYz/6c7kR6DBp2prn+W6KW1Xmz6vZtngtHo6j+rPoc86RfGoXM6tn8pTg1pRmG/h/TDp2nHil3yI26p1zHC2Rs6Jo1tO6+O50VWK0zeyJPtTZNfVTLt2jvzzD2N86yeG/qGUd24Kv8r0vzQXp+X2S+053oF34Rqqd0UNtTe0vC4DYOVFWOBlYrR63L/IxWXELJTIgALNYi0bB9y4eVGm5S+dAgh9ahnJB4tx19kT9lbrWtMm2/thwKNhJOavxL9+kTJhfsdtdx6vtbIZutNu41FJA5n7dMhuUaQWWV7W0y1GbVVKakYpePuj7mRAtzeNivP5vDnEAYfQRAxNhPt0MqDdm0aFoYiEsYMJXvPr180qMpLQ6ivQ7dFSYeWNT6/anqiKis+NyL0a2d/dGw/p1+Ml7s1rswNDxag4YrxKScuwPMKm8EftL1GakYhWb6B0byJagxLNIJWlo5Ax6CuQ655QjY60LAPKkO3mPCkqJG9TEAp9GqlHwb2/CqWcR9LuUgyfJhDs4oB6TWnj4f7m8NTdpRjLkpk6NJC4w7UHNKB9N5nS8/kkpxUhP+qNj+XGm3yhigqDDI3la4vyRUKpVEBVFVWmX8+39GsjmC5zyVBKhd6IbMpnVXgYcfsM0FON+tEqtDsT0e1LIPW4hHqICqmxcIBvq6jCAUUbfBzspjKBC+pB7nA8icQPDRiKE0k8KuMyRI27FWAlc8lQgeGGx19EXf3d6B+H7ugHfKDTsXK40lwuZB1Jm7VoNyehwxvNECV8msjUsVNJLKPhbQKGELXvS85YykvmDG+kLkFszIpD1QYnbQD4RRD1UDJRsVrLe19gOBRH0PgE8hp9nEpGN1OFOlb366N+cgWlenBwbu2k7QpXmnpfx70v3mc/QGv5aJzh4Frim3/J7QaPPfkElw4e4WsTQA0la7aTo4fHvJ6g5mih+X2aC0fYPHQTJaZudHU/zfEsS2Pw+b94Z83ppofOVnC12fc1lPj0grwj5mfL5bwFBE5NueWPiMgXjUjOTuYbRYXp6M7VXfuTuQy4+3hh+CDd8vEXI7oNC0hu7sOQ7r3oefYoH14AqCZpbAhrG30yVcZ4wRp7584AfJbxL07KchPtjz1/cr7Cp0Xm1aLvD/+L4zXm8L5PduZ4xnHzvvJJdsT+nVPNXNNrFy7TzuVhrIFrn5zivN68w8Nejlw5+jk/AFw4xZGh73O+3qONDz/pyJV8veVdtR+pypd5xMueH/Z+wJlPbbAd4s2T6wfQ5WwlFz/5mE/2fkeHJ93weGM4vbp9w7efN5027Hri93MhW8o64OfaHrduf6BMdxT9Yz3xaqfAy7U9x8osX3b4zylyDC54OTYWmQI3+58p/tJc7uWzpzj2UyselTSe49SKMq44O9F1yrM8FWrFt8U/tHz/lrhWybFTlea/f1lGmb0bzvyI8WoXnP9gDVwg6+hJ5Gsgd+iOt0sZh0+Zy2zp7tcZnWrZl6s0/WpZe7xGvsjAHs+yNiaaZQOfYNBf5rDur8MIbDB8SAtWlrrgrLxK8dmLABiL8jnW3PttTWis3rk87oShpNxc56uz0Z0w15SW1OUb4h/+DPLB5SR/1J3gYQpAicpbQV5WgaX+FJMw722Kbqg/EurQAM5sjkVr/xxBTdx0uNmdbO/vn1vvgg2ZpB0G75kRBHl5WwJdCB2ykqmWR7BW7ihlQmwEHt3AwT+CxPVRKJU0Gr5xW9H1cJf+Uax8wRuJCkDCvRckDvdBe94WdWwSUT1BIQWhUU5l1XANtofzGt7/UXdWztUSHB+Gz1E1UcPUSPnyjZOdtsLKnajYCBJGJFi+yOhC1LYkKiLjCHNPRO7ijmZhEgkhCpDVBPorWDxTRVinIlLHm+86yIeSyLzgQvBfw/D2sgyYH48gOD6QtAwdK1evJGnuJabO9cGlxgHvFzaSOMMdqVNj4YtJnFNFTKwPDiYHVC8tZru/BPmAlQveCh1hfZMotfLmtU0x+FuBYVgw7vsSCRsioS1aeVv54uOvQtqZT54BvK2SiHCfQO2rDRWhHiQrI8g8qyFvbzIVLnEsHqVm8abXCHs1hsB9Et4vJbDyJSVYKRsOB0qP5WFU+KC6z3dRGnRTmQDv15PYWDWVN4e7sAoHvIdvJHWhGsnKiGa4N4kbIvCWJCp2BJknpqKu/n50ccf/z3Xe8lK+RmJ8IWHxwQRbuRO0OpGox4FDRaTu1sJ4YFDD20i4XF+Llx6RwMoWh8eb+KLr/Wblzmt7kpBi41C7x4AVSC5qonYnEuEMcj4Y903F43jtGUioF+rYuDCJiJkxqHvFWJavbXEfnUTCMIkWr/9aPcEgz7PMHRMNGwc3vM3DQSx/4zgTJwayu5MNlzv2YeGSP7TqFNsPm8Cr+ctY138G7W2u0L7ni0x+FNo7TyDi6DLi+x6iPdZ0fXU6np0ccF//EptfnUnMZmswPYwqfgbtG526tcfV34nE6BkkmhYRMbzxZ+j8Z6wm8JUp+AwCbJyJWDoLBemtOpda7i9MxP3lSAafcELZZxxRL6UTN2cdmnd8UX0bSfBLEok757K9IJKIIRpsbC4jeUxnY6OTAwvlX5gf+wnRw9RswhrFoGjWPAnGrIY2tufZKf0Z/+oowrr9iW4vhBHZbR5LFh5lUUMrWkj8b/QMUl8aRWDGE3T3f4KeXcxDwV4zlxE8cS7Bagmbn+FPY5cR2sxIyzZEhW3IXt47/jAd+vaj1/hTFEQfwUn7DE8d3UtW30KseJBHXh3Fo52qOVNn33bDnuGpw3vJUn+KNT/Bk8+iHm6FdbEN51/ZSOmDNrT7GTrMfJY/PW7iYvweUtc/SLsHf8bKbQBPP9nMdeRRBjpVs/TsYJZ2BMm1O9Lpt1BMngaA3/AJPPPWdp5Z2h7kq7gFRfKyAhp+Zbw9AwODeTvhTfyK7XF+zBGvh0G+RsMrh/UpHuZ/vt1Lln8u7R6Ca9LjPLnt4Rbs2ArtHFH++++MnflvKv59hYGRi/F+yJrxw/YwLXIau//4R555NpxBaxOZmbOO5a+MZuKacPpvAxRqFsY6Qvve+F9axJjY9mxdNBrvxla+Lp9F394JF6D0c3Ab1r7p8Ga1Z9josex+cxpP5znh3sMZz84/3vKlkIY2XO8Uw6cTlTYDtWYXLq4DcPGUkNu1sC6PrXOAHiNRG1VsdNvJSktn4z1jDWGvzEatscHmZ3AJXU2EFTd+Bbv3GALlFKpGB7SyP5JQN9Xe6wF9ImHe2hvilfwXo9vUqgcy76oHfvnll1/udyKaZEojzDaMithC8ubUf+1cuG8OT8VVoyXo0Jes/PNdPI4xjTD3MCpevUv5b8onzltN8qBMzqxXt91B6W+BqKvCvfZhDB6bfChMDr1LdVcmOdSHwsgzDbZz/2do3YpZSx1QtqkvJV2n+anv/U5Cs77p0OR3Eu+Y7z89xIc1/Qj062we7I36ihnHF/BkK26HL2Ln3UvgbVqZ4nq/k0DMmC9ved81x9W3sFcla16JQ56+kzldb/nQzfrlp9tYBmuGsSKfw5d7MsrjITCkMTKuijmN/AqBB/v63NpBLhSQ9rE1Go0XkqmYN4fEIm3X8tpdvGY3OL2OwdNlVmbNuuGx+Jt0ML++U7pExdROSXzwyt2bfFVsGExYzcZ7Mva5A7+AWxDuIkUQcdHelG5q7e80a5mKtxaTcEHN32aKSZsg/BbJ+SsJrv0F3HeSqZTE8GBW5oslX+FmnaUf+CB2FIHqUQSG/Itu8ZGtmrQJwt2gaF/Dgbem8fSMaTy9MB+3v75453/vWydrqvbOQDVEw+AhMygMnEfEPZq05a/U4DP5GJpl05qetNVzZscEyy/gvgtpWhHMhB1nmt/wDmn7K26CIAiC0AaJFbe2516tuN0JYsWtafd+xe3euJsrbq1xyytuvxUdGv5g3m+dWHETBEEQBEEQBEFo48SKmyAIgiAIgiAIQhsnVtwEQRAEQRAEQRDaODFxEwRBEARBEARBaOPExE0QBEEQBEEQBKGNExM3QRAEQRAEQRCENk5M3ARBEARBEARBENo4MXETBEEQBEEQBEFo48TETRAEQRAEQRAEoY0TEzdBEARBEARBEIQ27v8DUW+d9qZRZe4AAAAASUVORK5CYII=\n",
      "text/plain": [
       "<IPython.core.display.Image object>"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import IPython.display\n",
    "IPython.display.Image(filename=\"bert_captum_visualization.png\")"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.9"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
